package com.wj.filter;

import com.wj.constant.CommonConstant;
import com.wj.util.TokenParseUtil;
import com.wj.vo.LoginUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

@Slf4j
@Component
public class LoginUserInfoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 不分请求不需要带有token，即白名单
        if (checkWhiteListUrl(request.getRequestURI())){
            return true;
        }

        //先尝试从 http header 中拿到 token
        String token = request.getHeader(CommonConstant.JWT_USER_INFO_KEY);
        LoginUserInfo loginUserInfo = null;
        try {
            //尝试从 token 中解析出用户信息
            loginUserInfo = TokenParseUtil.parseUserInfoFromToken(token);
        } catch (Exception e) {
            log.error("parse login user info error: {[]}", e.getMessage(),e);
        }
        //没有用户信息（这一步基本可能，因为我们在网关已经对 token 做了验证）
        if (Objects.isNull(loginUserInfo)){
            throw new RuntimeException("can not parse current login user");
        }
        // 将用户信息填充进 ThreadLocal
        AccessContext.setLoginUserInfo(loginUserInfo);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 在请求完全结束后调用，常用于清理资源等工作
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        if (Objects.nonNull(AccessContext.getLoginUserInfo())){
            AccessContext.clearLoginUserInfo();
        }
    }

    private boolean checkWhiteListUrl(String url){
        return StringUtils.containsAny(url,"springfox","swagger","v2",
                "webjars","doc.html");
    }
}
